package edu.friday.common.security.service;

import com.alibaba.fastjson.JSON;
import edu.friday.common.constant.Constants;
import edu.friday.common.security.LoginUser;
import edu.friday.utils.IdUtils;
import edu.friday.utils.RedisCache;
import edu.friday.utils.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class TokenService {
    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    // 令牌有效期（默认30分钟）
    @Value("${token.expireTime}")
    private int expireTime;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;

    @Autowired
    private RedisCache redisCache;

    public String creteToken(LoginUser loginUser) {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        String userKey = Constants.LOGIN_TOKEN_KEY + loginUser.getToken();
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
        System.out.println(userKey);
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY,token);
        return getToken(claims);
    }
    public String getToken(Map<String, Object> claims){
        return Jwts
                .builder().setClaims(claims)
                .signWith(SignatureAlgorithm.HS512,secret).compact();
    }

    public Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }
    
    public LoginUser getLoginUser(HttpServletRequest request){
        String token = request.getHeader(header);
        if(StringUtils.isEmpty(token))
            return null;
        if (token.startsWith(Constants.TOKEN_PREFIX))
            token = token.replace(Constants.TOKEN_PREFIX, "");
        System.out.println(token);
        try {
            Claims claims = parseToken(token);
            String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
            String userKey = Constants.LOGIN_TOKEN_KEY + uuid;
            LoginUser loginUser = JSON.parseObject(JSON.toJSONString(redisCache.getCacheObject(userKey)), LoginUser.class);
            return loginUser;
        } catch (Exception e) {
            throw new RuntimeException("token校验失败");
        }
    }
}
